package com.hyhy.hycloud.commons.support;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.hyhy.hycloud.commons.helper.HycloudDateFormat;
import com.hyhy.hycloud.commons.helper.HycloudLocalDateDeserializer;
import com.hyhy.hycloud.commons.helper.HycloudLocalDateTimeDeserializer;
import com.hyhy.hycloud.commons.helper.HycloudLocalTimeDeserializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.jackson.JacksonProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * @author lanpengfei
 * @date 2018/12/24
 */
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnMissingClass("org.springframework.http.converter.json.Jackson2ObjectMapperBuilder")
@EnableConfigurationProperties(JacksonProperties.class)
public class ObjectMapperConfig {
    @Autowired
    private JacksonProperties jacksonProperties;

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        if (!CollectionUtils.isEmpty(jacksonProperties.getDeserialization())) {
            jacksonProperties.getDeserialization().forEach(objectMapper::configure);
        }
        if (!CollectionUtils.isEmpty(jacksonProperties.getSerialization())) {
            jacksonProperties.getSerialization().forEach(objectMapper::configure);
        }
        DateFormat dateFormat = new HycloudDateFormat(objectMapper.getDateFormat());
        if (jacksonProperties.getTimeZone() != null) {
            objectMapper.setTimeZone(jacksonProperties.getTimeZone());
            dateFormat.setTimeZone(jacksonProperties.getTimeZone());
        }
        objectMapper.setDateFormat(dateFormat);
        JavaTimeModule module = new JavaTimeModule();

        module.addDeserializer(LocalDateTime.class, HycloudLocalDateTimeDeserializer.INSTANCE);
        module.addDeserializer(LocalDate.class, HycloudLocalDateDeserializer.INSTANCE);
        module.addDeserializer(LocalTime.class, HycloudLocalTimeDeserializer.INSTANCE);

        if (!StringUtils.isEmpty(jacksonProperties.getDateFormat())) {
            module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(jacksonProperties.getDateFormat())));
        }
        objectMapper.registerModule(module);
        return objectMapper;
    }

}
